CCreateCircle 类

CCreateCircle类定义交互绘圆时对鼠标事件的响应,它实现了ICommand 接口。用鼠标绘圆,需要定义圆的控制点的位置。本书采用圆心和圆上一点绘圆,所以需要确定圆心和圆上一点的位置。用鼠标交互绘圆的大体思路是:把鼠标左键的第1个单击点作为圆心,把第2个单击点作为圆上一点,两次单击之间的过程用橡皮线和橡皮圆描述,单击右键取消操作与CCreateLine类一样,CCreateCircle类要实现ICommand接口的全部方法。用m_Step记录鼠标左键的单击次数并控制不同的绘图操作,用m_Center和m_pCircle记录圆心和圆上一点的位置。

LButtonDown方法描述单击鼠标左键时的绘图行为。第1次单击鼠标左键时,将当前点作为圆心。第2次单击时,确定圆上一点,并删除最后一条橡皮线和最后一个橡皮圆,然后用正常模式绘当前圆。将新创建的圆添加到图元集合类中保存,以备重画和编辑之用。将m_Step归0。

code.vb.net
'创建圆类
Public Class CCreateCircle
    Implements ICommand
    Private m_Step As Integer
    Private m_Center, m_pCircle As PointF
    Public Sub LButtonDown(ByVal g As Graphics, ByVal aPos As PointF) Implements ICommand.LButtonDown
        '记录鼠标左键的单击次数
        m_Step += 1
        Select Case m_Step
            Case 1               '第1次单击鼠标左键
                m_Center = aPos
                m_pCircle = aPos
            Case 2
                '清除最后一次拖动时显示的橡皮线
                Dim tempLine As New CLine(m_Center, m_pCircle)
                tempLine.Draw(g, CGElement.geDrawMode.Drag)
                tempLine = Nothing
                '清除最后一次拖动时显示的橡皮圆
                Dim tempCircle As New CCircle(m_Center, m_pCircle)
                tempCircle.Draw(g, CGElement.geDrawMode.Normal)
                tempCircle = Nothing
                '绘当前位置的圆
                Dim newCircle As New CCircle(m_Center, aPos)
                newCircle.Draw(g, CGElement.geDrawMode.Normal)
                '图元个数加1,作为新建圆的ID号
                geNum += 1
                ges.Add(newCircle)
                m_Step = 0
        End Select
    End Sub
End Class

MouseMove方法定义鼠标在绘图区中移动时的绘图行为。第1次单击鼠标左键,确定圆心的位置以后,移动鼠标,绘制橡皮线和橡皮圆。橡皮线连接圆心和鼠标光标当前点,橡皮圆为以橡皮线长度为半径的圆,橡皮线和橡皮圆随鼠标光标位置的改变而改变方向、长度或大小。在实际绘制的过程中,需要首先清除上一位置的橡皮线和橡皮圆,然后绘制当前位置的橡皮线和橡皮圆。绘制完毕以后,需要将当前点赋给m_pCircle,因为圆上一点是动态给定的,当前位置的点在绘制下一个橡皮线和橡皮圆时它就变成了上一个点。所以需要记录它,以便绘下一条橡皮线之前删除橡皮线和橡皮圆。

code.vb.net
    Public Sub MouseMove(ByVal g As Graphics, ByVal aPos As PointF) Implements ICommand.MouseMove
        Select Case m_Step
            Case 1
                Dim prePos As New PointF()
                Dim curPos As New PointF()
                prePos = m_pCircle
                curPos = aPos
                '清除上一条橡皮线
                Dim tempLine1 As New CLine(m_Center, prePos)
                tempLine1.Draw(g, CGElement.geDrawMode.Drag)
                tempLine1 = Nothing
                '清除上一个橡皮圆
                Dim tempCircle1 As New CCircle(m_Center, prePos)
                tempCircle1.Draw(g, CGElement.geDrawMode.Drag)
                tempCircle1 = Nothing
                '绘当前位置的橡皮线
                Dim tempLine2 As New CLine(m_Center, curPos)
                tempLine2.Draw(g, CGElement.geDrawMode.Drag)
                tempLine2 = Nothing
                '绘当前位置的橡皮圆
                Dim tempCircle2 As New CCircle(m_Center, curPos)
                tempCircle2.Draw(g, CGElement.geDrawMode.Drag)
                tempCircle2 = Nothing
                m_pCircle = curPos
        End Select
    End Sub

第1次单击鼠标左键以后,绘图工作已经进行了一半,此时因为某种原因想取消操作,就用RButonDown方法来实现。取消操作需要清除最后一条橡皮线和橡皮圆。然后将m_Step归0。

code.vb.net
    '单击鼠标右键时的绘图行为
    Public Sub RButtonDown(ByVal g As Graphics, ByVal aPos As PointF) Implements ICommand.RButtonDown
        If m_Step = 1 Then
            '清除橡皮线
            Dim tempLine As New CLine(m_Center, m_pCircle)
            tempLine.Draw(g, CGElement.geDrawMode.Drag)
            tempLine = Nothing
            '清除橡皮圆
            Dim tempCircle As New CCircle(m_Center, m_pCircle)
            tempCircle.Draw(g, CGElement.geDrawMode.Drag)
            tempCircle = Nothing
        End If
        m_Step = 0
    End Sub